home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 2: Applications / Linux Cubed Series 2 - Applications.iso / math / gle-3.000 / gle-3 / gle / core.c < prev    next >
C/C++ Source or Header  |  1995-02-07  |  28KB  |  998 lines

  1. /*--------------------------------------------------------------*/
  2. /*        CORE, for GLE V3.0                                         */
  3. /*--------------------------------------------------------------*/
  4.  
  5. /* g_scr_* needs to be added */
  6. /* g_int_* needs to be decided/added */
  7. /* g_tex_* needs to be decided/added */
  8.  
  9. /*---------------------------------------------------------------------------*/
  10. #include <math.h>
  11. #include "all.h"
  12. #include "mygraph.h"
  13. #include "mydev.h"
  14. #include "core.h"
  15. #include "justify.h"
  16. int mystrncmp(char *a, char *b, int n);
  17. struct gmodel g;
  18. double tmpimg[3][3];
  19. double tmpimg2[3][3];
  20. double font_lwidth;
  21. /*---------------------------------------------------------------------------*/
  22. #if (defined M_PI && !defined PI)
  23. #define PI M_PI
  24. #define pi M_PI
  25. #elif defined PI
  26. #define pi PI
  27. #else
  28. #define PI 3.141592653
  29. #define pi 3.141592653
  30. #endif
  31.  
  32. #define true (!false)
  33. #define false 0
  34. #define dbg if ((gle_debug & 32)>0)
  35. extern int gle_debug;
  36. /*---------------------------------------------------------------------------*/
  37. /* The global variables that CORE keeps track of */
  38. /*-----------------------------------------------*/
  39.  
  40. static int jj;
  41. int test_unit(void);
  42. int gunit=false;
  43. #define color_black 0X01000000
  44. /*---------------------------------------------------------------------------*/
  45.  
  46. /*---------------------------------------------------------------------------*/
  47. g_dfont(char *s)
  48. {
  49.         d_dfont(s);
  50. }
  51. /*---------------------------------------------------------------------------*/
  52. int32 g_get_grey(double v)
  53. {
  54.         colortyp c;
  55.         c.b[B_F] = 1;
  56.         c.b[B_R] = 255*v;
  57.         c.b[B_G] = 255*v;
  58.         c.b[B_B] = 255*v;
  59.         return c.l;
  60. }
  61. /*---------------------------------------------------------------------------*/
  62. g_hint(char *s)
  63. {
  64.         gprint("%s\n",s);
  65. }
  66. /*---------------------------------------------------------------------------*/
  67. extern int noscreenio;
  68. g_message(char *s)
  69. {
  70. #ifdef EMXOS2
  71.         extern FILE *ErrFileSURFOS2;
  72.         extern int flagSURFOS2;
  73.  
  74.         if (flagSURFOS2)
  75.                {
  76.                 fputs(s,ErrFileSURFOS2);
  77.                 fputs("\n",ErrFileSURFOS2);
  78.                 return;
  79.                }
  80. #endif
  81.         if (noscreenio) printf("%s\n",s);
  82.         else d_message(s);
  83. }
  84. /*---------------------------------------------------------------------------*/
  85. g_source(char *s)
  86. {
  87.         d_source(s);
  88. }
  89. /*---------------------------------------------------------------------------*/
  90. g_get_end(dbl *x,dbl *y)
  91. {
  92.         *x = tex_xend();
  93.         *y = tex_yend();
  94. }
  95. g_set_end(dbl x,dbl y)
  96. {
  97.         gprint("What is setting end \n");
  98. }
  99. /*---------------------------------------------------------------------------*/
  100. g_get_usersize(dbl *x,dbl *y)
  101. {                /* Does this want device size, or user size ????? */
  102.         *x = g.userwidth;
  103.         *y = g.userheight;
  104. }
  105. g_get_devsize(dbl *x,dbl *y)
  106. {                /* Does this want device size, or user size ????? */
  107.         *x = g.devwidth;
  108.         *y = g.devheight;
  109. }
  110. /*---------------------------------------------------------------------------*/
  111. g_get_bounds(dbl *x1,dbl *y1,dbl *x2,dbl *y2)
  112. {
  113.         *x1 = g.xmin;
  114.         *y1 = g.ymin;
  115.         *x2 = g.xmax;
  116.         *y2 = g.ymax;
  117. }
  118. /*---------------------------------------------------------------------------*/
  119. g_init_bounds()
  120. {
  121.         g.xmin = 1e30;
  122.         g.ymin = 1e30;
  123.         g.xmax = -1e30;
  124.         g.ymax = -1e30;
  125. }
  126. /*---------------------------------------------------------------------------*/
  127. g_get_type(char *t)
  128. {
  129.         d_get_type(t);
  130. }
  131. /*---------------------------------------------------------------------------*/
  132. g_set_path(int onoff)
  133. {
  134.         if (onoff==g.inpath) return;
  135.         g_flush();
  136.         if (onoff==true) {
  137.                 g.inpath=true;
  138.                 g.npath = 0;
  139.                 g.xinline=false;
  140.         } else {
  141.                 g.inpath = false;
  142.                 g.xinline = false;
  143.         }
  144.         d_set_path(onoff);
  145. }
  146. /*---------------------------------------------------------------------------*/
  147. g_get_path(int *onoff)
  148. {
  149.         *onoff = g.inpath;
  150. }
  151. /*---------------------------------------------------------------------------*/
  152. g_newpath()
  153. {
  154.         g.npath = 0;
  155.         d_newpath();
  156. }
  157. /*---------------------------------------------------------------------------*/
  158. static int isopen=0;
  159. g_open(dbl width,dbl height)
  160. {
  161.         if (isopen) return;
  162.         isopen = true;
  163.         if (width*height==0) {
  164.           gprint("G_OPEN, Width or height was zero w=%g, h=%g\n",width,height);
  165.           width = 10; height = 10;        /* format was "%d" a.r. */
  166.         }
  167.         g.userwidth = width;
  168.         g.userheight = height;
  169.         freeafont();
  170.         d_open(width,height);
  171.         g_clear();
  172. }
  173. /*---------------------------------------------------------------------------*/
  174. g_close()
  175. {
  176.         isopen = false;
  177.         g_flush();
  178.         d_close();
  179. }
  180. /*---------------------------------------------------------------------------*/
  181. g_set_line_cap(int i)
  182. {
  183.         /*  lcap, 0= butt, 1=round, 2=projecting square */
  184.         if (i<0 || i>2) {
  185.                 gprint("Invalid line cap, {%d}, valid numbers are \n",i);
  186.                 gprint("        0= butt, 1=round, 2=projecting square \n");
  187.         }
  188.         d_set_line_cap(i);
  189.         g.lcap = i;
  190. }
  191. /*---------------------------------------------------------------------------*/
  192. g_set_line_join(int i)
  193. {
  194.         if (i<0 || i>2) {
  195.                 gprint("Invalid line join, {%d}, valid numbers are \n",i);
  196.                 gprint("        0= mitre, 1=round, 2=bevel \n");
  197.         }
  198.         d_set_line_join(i);
  199.         g.ljoin = i;
  200. }
  201. g_get_line_join(int *i)
  202. {
  203.         *i = g.ljoin;
  204. }
  205. g_get_line_cap(int *i)
  206. {
  207.         *i = g.lcap;
  208. }
  209. /*---------------------------------------------------------------------------*/
  210. g_set_line_miterlimit(double d)
  211. {
  212.         d_set_line_miterlimit(d);
  213.         g.miterlimit = d;
  214. }
  215. /*---------------------------------------------------------------------------*/
  216. g_get_line_width(double *w)
  217. {
  218.         *w = g.lwidth;
  219. }
  220. /*---------------------------------------------------------------------------*/
  221. g_set_line_width(double w)
  222. {
  223.         if (w<0) return;
  224.         d_set_line_width(w);
  225.         g.lwidth = w;
  226. }
  227. g_set_font_width(double w)
  228. {
  229.         font_lwidth = w;
  230. }
  231. /*---------------------------------------------------------------------------*/
  232. g_get_line_styled(double *w)
  233. {
  234.         *w = g.lstyled;
  235. }
  236. /*---------------------------------------------------------------------------*/
  237. g_set_line_styled(double w)
  238. {
  239.         if (w==0) return;
  240.         d_set_line_styled(w);
  241.         g.lstyled = w;
  242. }
  243. /*---------------------------------------------------------------------------*/
  244. g_set_line_style(char *s)
  245. {
  246.         d_set_line_style(s);
  247.         strncpy(g.lstyle,s,8);
  248. }
  249. /*---------------------------------------------------------------------------*/
  250. g_get_line_style(char *s)
  251. {
  252.         strncpy(s,(char *) &g.lstyle,8);
  253. }
  254. /*---------------------------------------------------------------------------*/
  255. g_dev(double x, double y,double *xd,double *yd)
  256. {
  257.         static double xx,yy;
  258.         if (gunit==true) { *xd = x; *yd = y; }
  259.         else {
  260.         xx = g.image[0][0]*x + g.image[0][1]*y + g.image[0][2];
  261.         yy = g.image[1][0]*x + g.image[1][1]*y + g.image[1][2];
  262.         *xd = xx;
  263.         *yd = yy;
  264.         }
  265. }
  266. /*---------------------------------------------------------------------------*/
  267. g_undev(double ux,double uy, double *x,double *y)
  268. {
  269.         static double xx,yy,cdiv,xd,yd;
  270.         if (gunit==true) { *x = ux; *y = uy; }
  271.         else {
  272.         cdiv = ( g.image[0][1]*g.image[1][0] - g.image[0][0]*g.image[1][1] );
  273.         if (cdiv==0) {gprint("Image matrix FLAT, a 1D world, giving up \n");return;}
  274.         xd = ux - g.image[0][2];
  275.         yd = uy - g.image[1][2];
  276.         xx = -xd*g.image[1][1] + yd*g.image[0][1];
  277.         *x = xx/cdiv;
  278.         yy = xd*g.image[1][0]-yd*g.image[0][0];
  279.         *y = yy/cdiv;
  280.         }
  281. }
  282. /*---------------------------------------------------------------------------*/
  283. g_rundev(double x, double y,double *xd,double *yd)
  284. {
  285.         static double zx,zy;
  286.         g_undev(0,0,&zx,&zy);
  287.         g_undev(x,y,xd,yd);
  288.         *xd -= zx;
  289.         *yd -= zy;
  290. }
  291. g_rdev(double x, double y,double *xd,double *yd)
  292. {
  293.         static double zx,zy;
  294.         g_dev(0,0,&zx,&zy);
  295.         g_dev(x,y,xd,yd);
  296.         *xd -= zx;
  297.         *yd -= zy;
  298. }
  299. /*---------------------------------------------------------------------------*/
  300. g_fill()
  301. {
  302.         d_fill();
  303. }
  304. /*---------------------------------------------------------------------------*/
  305. g_fill_ary(int nwk,double (*wkx)[],double (*wky)[])
  306. {
  307.         d_fill_ary(nwk,wkx,wky);
  308. }
  309. g_line_ary(int nwk,double (*wkx)[],double  (*wky)[])
  310. {
  311.         d_line_ary(nwk,wkx,wky);
  312. }
  313. /*---------------------------------------------------------------------------*/
  314. g_stroke()
  315. {
  316.         d_stroke();
  317. }
  318. /*---------------------------------------------------------------------------*/
  319. g_clip()
  320. {
  321.         /* Find the intersection of the current path with the clipping path */
  322.         /* and thus define a new clipping path */
  323.         d_clip();
  324. }
  325. /*---------------------------------------------------------------------------*/
  326. g_set_matrix(double newmat[3][3])
  327. {
  328.         static double x1,y1,x2,y2,x3,y3,x4,y4;
  329.         static double a1,b1,a2,b2,a3,b3,a4,b4;
  330.  
  331.         g_dev(g.xmin,g.ymin,&x1,&y1);
  332.         g_dev(g.xmax,g.ymin,&x2,&y2);
  333.         g_dev(g.xmax,g.ymax,&x3,&y3);
  334.         g_dev(g.xmin,g.ymax,&x4,&y4);
  335.  
  336.         if (memcmp(newmat,g.image,3*3*8)!=0) d_set_matrix(newmat);
  337.         memcpy(&g.image,newmat,3*3*8);
  338.  
  339.         g_init_bounds();
  340.  
  341.         if (g.xmin<g.xmax)  {
  342.                 g_undev(x1,y1,&a1,&b1);
  343.                 g_undev(x2,y2,&a2,&b2);
  344.                 g_undev(x3,y3,&a3,&b3);
  345.                 g_undev(x4,y4,&a4,&b4);
  346.                 g_set_bounds(a1,b1);
  347.                 g_set_bounds(a2,b2);
  348.                 g_set_bounds(a3,b3);
  349.                 g_set_bounds(a4,b4);
  350.         }
  351. }
  352. /*---------------------------------------------------------------------------*/
  353. mat_mult(double a[3][3],double b[3][3])
  354. {
  355.         static double c[3][3],tot;
  356.         int y,xb,x;
  357.         for (y=0;y<3;y++) {
  358.           for (xb=0;xb<3;xb++) {
  359.                 tot = 0;
  360.                 for (x=0;x<3;x++) tot += a[x][y] * b[xb][x];
  361.                 c[xb][y] = tot;
  362.           }
  363.         }
  364.         memcpy(a,&c,3*3*8);        /* maybe sizeof(*a) would be better? */
  365. }
  366. /*---------------------------------------------------------------------------*/
  367. g_rotate(double ar)
  368. {
  369.         static double r[3][3],unx,uny,cx,cy;
  370.         ar = pi*ar/180;
  371.         r[0][0] = cos(ar);
  372.         r[0][1] = -sin(ar);
  373.         r[1][0] = sin(ar);
  374.         r[1][1] = cos(ar);
  375.         r[2][2] = 1;
  376.         g_dev(g.curx,g.cury,&cx,&cy);
  377.         g_rundev(-cx,-cy,&unx,&uny);
  378.         g_translate(unx,uny);
  379.         memcpy(tmpimg,g.image,3*3*8);
  380.         mat_mult(tmpimg,r);
  381.         g_set_matrix(tmpimg);
  382.         g_rundev(cx,cy,&unx,&uny);
  383.         g_translate(unx,uny);        /* not shore about this ORIGIN stuff */
  384.         test_unit();
  385. }
  386. /*---------------------------------------------------------------------------*/
  387. int gg_unrotate(void);
  388. int gg_rerotate(void);
  389. g_scale(double sx,double sy)
  390. {
  391.         /* The idea is to rotate or scale about the CURRENT POINT */
  392.         static double r[3][3],unx,uny,cx,cy;
  393.         r[0][0] = sx;
  394.         r[1][1] = sy;
  395.         r[2][2] = 1;
  396.  
  397.         gg_unrotate();
  398.         g_dev(g.curx,g.cury,&cx,&cy);
  399.         g_rundev(-cx,-cy,&unx,&uny);
  400.         g_translate(unx,uny);
  401.         memcpy(tmpimg,g.image,3*3*8);
  402.         mat_mult(tmpimg,r);
  403.         g_set_matrix(tmpimg);
  404.         g_rundev(cx,cy,&unx,&uny);
  405.         g_translate(unx,uny);        /* not shore about this ORIGIN stuff */
  406.         gg_rerotate();
  407.         test_unit();
  408. }
  409. void g_shear(double sx,double sy)
  410. {
  411.         /* The idea is to rotate or scale about the CURRENT POINT */
  412.         static double r[3][3],unx,uny,cx,cy;
  413.         r[0][0] = 1;
  414.         r[1][0] = sy;
  415.         r[1][1] = 1;
  416.         r[0][1] = sx;
  417.         r[2][2] = 1;
  418.  
  419.         gg_unrotate();
  420.         g_dev(g.curx,g.cury,&cx,&cy);
  421.         g_rundev(-cx,-cy,&unx,&uny);
  422.         g_translate(unx,uny);
  423.         memcpy(tmpimg,g.image,3*3*8);
  424.         mat_mult(tmpimg,r);
  425.         g_set_matrix(tmpimg);
  426.         g_rundev(cx,cy,&unx,&uny);
  427.         g_translate(unx,uny);        /* not shore about this ORIGIN stuff */
  428.         gg_rerotate();
  429.         test_unit();
  430. }
  431. static double ggra;
  432. gg_rerotate()
  433. {
  434.         g_rotate(ggra);
  435. }
  436. gg_unrotate()
  437. {
  438.         double ox,oy,x1,y0,dx,dy,tt;
  439.         g_dev(0.0,0.0,&ox,&oy);
  440.         g_dev(1.0,0.0,&x1,&y0);
  441.         dx = x1-ox;
  442.         dy = y0-oy;
  443.         tt = myatan2(dy,dx);
  444.         ggra = tt * 180.0 / PI;
  445.         g_rotate(-ggra);
  446. }
  447.  
  448. /*---------------------------------------------------------------------------*/
  449. dis_mat(char *s,double m[3][3])
  450. {
  451.         int i,j;
  452.         gprint("\n Matrix {%s} \n",s);
  453.         for (i=0;i<3;i++)
  454.                 gprint("        %f %f %f \n",m[0][i],m[1][i],m[2][i]);
  455.  
  456. }
  457. /*---------------------------------------------------------------------------*/
  458. g_translate(double ztx,double zty)
  459. {
  460.         static double tx,ty,r[3][3];
  461.         g_rdev(ztx,zty,&tx,&ty);
  462.  
  463.         r[0][0] = 1;
  464.         r[1][1] = 1;
  465.         r[2][2] = 1;
  466.         r[0][2] = tx;
  467.         r[1][2] = ty;
  468.         memcpy(tmpimg,g.image,3*3*8);
  469.         mat_mult(tmpimg,r);
  470.         g_set_matrix(tmpimg);
  471.         test_unit();
  472. }
  473. /*---------------------------------------------------------------------------*/
  474. g_move(double zx,double zy)
  475. {
  476.         double x,y;
  477.         if (g.xinline==true) g_flush();
  478.         d_move(zx,zy);
  479.         g.curx = zx;
  480.         g.cury = zy;
  481.         g.closex = zx;
  482.         g.closey = zy;
  483. }
  484. g_rmove(double zx,double zy)
  485. {
  486.         g_move(g.curx+zx,g.cury+zy);
  487. }
  488. g_rline(double zx,double zy)
  489. {
  490.         g_line(g.curx+zx,g.cury+zy);
  491. }
  492. /*---------------------------------------------------------------------------*/
  493. g_reverse()         /* reverse the order of stuff in the current path */
  494. {        d_reverse();        }
  495. /*---------------------------------------------------------------------------*/
  496. g_closepath()
  497. {
  498.         if (g.inpath) d_closepath();
  499.         else g_line(g.closex,g.closey);
  500.         g.curx = g.closex;
  501.         g.cury = g.closey;
  502.         if (!g.inpath) g_flush();
  503. }
  504. /*---------------------------------------------------------------------------*/
  505. g_line(double zx,double zy)
  506. {
  507.         double x,y;
  508.         d_line(zx,zy);
  509.         if (g.xinline==false) {
  510.                 g.xinline = true;
  511.                 g_set_bounds(g.curx,g.cury);
  512.         }
  513.         g.curx = zx;
  514.         g.cury = zy;
  515.         g_set_bounds(zx,zy);
  516. }
  517. /*---------------------------------------------------------------------------*/
  518. g_set_bounds(double x,double y)
  519. {
  520.         if (x<g.xmin) g.xmin = x;
  521.         if (x>g.xmax) g.xmax = x;
  522.         if (y<g.ymin) g.ymin = y;
  523.         if (y>g.ymax) g.ymax = y;
  524. }
  525. /*---------------------------------------------------------------------------*/
  526. test_unit()
  527. {
  528.         int i,j;
  529.         gunit = true;
  530.         for (i=0;i<3;i++) for (j=0;j<3;j++) if (i!=j) if(g.image[i][j]!=0.0) gunit = false;
  531.         for (i=0;i<3;i++) if (g.image[i][i]!=1.0) gunit = false;
  532. }
  533. /*
  534.         for (i=0;i<3;i++) {
  535.                 gprint("Matrix %g %g %g \n",g.image[i][0]
  536.                         ,g.image[i][1],g.image[i][2]);
  537.         }
  538. */
  539. int tex_clear(void);
  540. g_clear()
  541. {
  542.         int i,j;
  543.         for (i=0;i<3;i++) for (j=0;j<3;j++) g.image[i][j] = 0;
  544.         for (i=0;i<3;i++) g.image[i][i] = 1;
  545.         d_clear();
  546.         tex_clear();
  547.         g_set_just(JUST_LEFT);
  548.         g_set_line_styled(.04);
  549.         g_set_line_style("1");
  550.         g_set_line_width(0);
  551.         g_set_color(color_black);
  552.         g_set_fill(color_black);
  553.         g_set_font(1);         /*        Load and set default font         */
  554.         g_set_font_width(-1);         /*        Load and set default font         */
  555.         g_set_hei(1.0);        /*        And set to 1 cm size                  */
  556.         g_move(0.0,0.0);
  557.         test_unit();
  558.  
  559. }
  560. /*---------------------------------------------------------------------------*/
  561. g_get_xy(double *x,double *y)
  562. {
  563.         *x = g.curx;
  564.         *y = g.cury;
  565. }
  566. g_set_xy(double x, double y)        /* a synonym for MOVE */
  567. {        g_move(x,y); }
  568. /*---------------------------------------------------------------------------*/
  569. g_flush()
  570. {
  571.         d_flush();
  572.         g.xinline = false;
  573. }
  574. /*---------------------------------------------------------------------------*/
  575. g_arcto(dbl x1,dbl y1,dbl x2,dbl y2,dbl rrr)
  576. {
  577.         d_arcto(x1,y1,x2,y2,rrr);
  578.  
  579.         g.curx = x2;
  580.         g.cury = y2;
  581.         g.xinline = true;
  582.         /* should do MASSES of calc to find bounds of arc  */
  583.         g_set_bounds(x1,y1);
  584.         g_set_bounds(x2,y2);
  585. }
  586. /*---------------------------------------------------------------------------*/
  587. g_arc(dbl r,dbl t1,dbl t2,dbl cx,dbl cy)
  588. {
  589.         d_arc(r,t1,t2,cx,cy);
  590.         g.xinline = true;
  591.         if ((cx!=g.curx) || (cy!=g.cury)) {
  592.                 g.curx = cx + r*cos(pi*t2/180);
  593.                 g.cury = cy + r*sin(pi*t2/180);
  594.         }
  595. }
  596. /*---------------------------------------------------------------------------*/
  597. g_narc(dbl r,dbl t1,dbl t2,dbl cx,dbl cy)
  598. {
  599.         d_narc(r,t1,t2,cx,cy);
  600.         g.xinline = true;
  601.         if ((cx!=g.curx) || (cy!=g.cury)) {
  602.                 g.curx = cx + r*cos(pi*t2/180);
  603.                 g.cury = cy + r*sin(pi*t2/180);
  604.         }
  605. }
  606. /*---------------------------------------------------------------------------*/
  607. g_dojust(dbl *x1, dbl *y1, dbl *x2, dbl *y2, int jj)
  608. {
  609.         static int jx,jy;
  610.         static double w,y,d;
  611.         jx = (jj & 0xf0) / 16;
  612.         jy = jj & 0x0f;
  613.         d = jx * (*x2-*x1)/2;
  614.         *x1 -= d;
  615.         *x2 -= d;
  616.         d = jy * (*y2-*y1)/2;
  617.         *y1 -= d;
  618.         *y2 -= d;
  619. }
  620. g_dotjust(dbl *x1, dbl *y1, dbl l, dbl r, dbl u, dbl d, int jj)
  621. {
  622.         static int jx,jy,t;
  623.         static double ddd;
  624.         jx = (jj & 0xf0) / 16;
  625.         jy = jj & 0x0f;
  626.         t = (jj & 0xf00) / 256 ;
  627.         ddd = jx * (-l+r)/2;
  628.         *x1 = *x1 + -l - ddd;
  629.         ddd = jy * (u-d)/2;
  630.         if (t==0) *y1 = *y1 - d - ddd;
  631. }
  632. g_box_stroke(dbl x1, dbl y1, dbl x2, dbl y2)
  633. {
  634.         double x,y;
  635.         g_get_xy(&x,&y);
  636.         d_box_stroke(x1,y1,x2,y2);
  637.         g_set_bounds(x1,y1);
  638.         g_set_bounds(x2,y2);
  639.  
  640.         g_move(x,y);
  641. }
  642. /*---------------------------------------------------------------------------*/
  643. g_box_fill(dbl x1, dbl y1, dbl x2, dbl y2)
  644. {
  645.         double x,y;
  646.         g_get_xy(&x,&y);
  647.         d_box_fill(x1,y1,x2,y2);
  648.         g_set_bounds(x1,y1);
  649.         g_set_bounds(x2,y2);
  650.         g_move(x,y);
  651. }
  652. /*---------------------------------------------------------------------------*/
  653. g_circle_stroke(dbl zr)
  654. {
  655.         d_circle_stroke(zr);
  656.         g_set_bounds(g.curx-zr,g.cury-zr);
  657.         g_set_bounds(g.curx+zr,g.cury+zr);
  658. }
  659. g_circle_fill(dbl zr)
  660. {
  661.         d_circle_fill(zr);
  662.         g_set_bounds(g.curx-zr,g.cury-zr);
  663.         g_set_bounds(g.curx+zr,g.cury+zr);
  664. }
  665. /*---------------------------------------------------------------------------*/
  666. g_bezier(dbl x1,dbl y1,dbl x2,dbl y2,dbl x3,dbl y3)
  667. {
  668.         double x,y;
  669.         d_bezier(x1,y1,x2,y2,x3,y3);
  670.         if (g.xinline==false) {
  671.                 g.xinline = true;
  672.                 g_set_bounds(g.curx,g.cury);
  673.         }
  674.         g.curx = x3;
  675.         g.cury = y3;
  676.         g_set_bounds(x3,y3);
  677. }
  678. /*---------------------------------------------------------------------------*/
  679. g_dmove(double x, double y)
  680. {
  681.         double ux,uy;
  682.         g_undev(x,y,&ux,&uy);
  683.         d_move(ux,uy);
  684.         g.curx = ux;
  685.         g.cury = uy;
  686. }
  687. /*---------------------------------------------------------------------------*/
  688. g_dline(double x, double y)
  689. {
  690.         double ux,uy;
  691.         g_undev(x,y,&ux,&uy);
  692.         d_line(ux,uy);
  693.         g.curx = ux;
  694.         g.cury = uy;
  695. }
  696. /*---------------------------------------------------------------------------*/
  697. g_dbezier(dbl x1,dbl y1,dbl x2,dbl y2,dbl x3,dbl y3)
  698. {
  699.         double a1,b1,a2,b2,a3,b3;
  700.         g_undev(x1,y1,&a1,&b1);
  701.         g_undev(x2,y2,&a2,&b2);
  702.         g_undev(x3,y3,&a3,&b3);
  703.         g_bezier(a1,b1,a2,b2,a3,b3);
  704.         g.curx = a3;
  705.         g.cury = b3;
  706. }
  707. /*---------------------------------------------------------------------------*/
  708. g_bitmap(char *bmap)
  709. {
  710. }
  711. /*---------------------------------------------------------------------------*/
  712. g_set_rgbf(double rr, double gg, double bb, double ff)
  713. {
  714.         /* Fill pattern is left as-is */
  715.         g.color.b[B_R] = rr*255;
  716.         g.color.b[B_G] = gg*255;
  717.         g.color.b[B_B] = bb*255;
  718.         g.color.b[B_F] = ff*255;
  719.         d_set_color(g.color.l);
  720. }
  721. g_set_rgbf_fill(double rr, double gg, double bb, double ff)
  722. {
  723.         /* Fill pattern is left as-is */
  724.         g.fill.b[B_R] = rr*255;
  725.         g.fill.b[B_G] = gg*255;
  726.         g.fill.b[B_B] = bb*255;
  727.         g.fill.b[B_F] = ff*255;
  728.         d_set_fill(g.fill.l);
  729. }
  730. g_get_rgbf(double *rr, double *gg, double *bb, double *ff)
  731. {
  732.         *rr = g.color.b[B_R]/255;
  733.         *gg = g.color.b[B_G]/255;
  734.         *bb = g.color.b[B_B]/255;
  735.         *ff = g.color.b[B_F]/255;
  736. }
  737. /*---------------------------------------------------------------------------*/
  738. g_set_color(int32 l)
  739. {
  740.         if (l==0) return;
  741.         g.color.l = l;
  742.         d_set_color(g.color.l);
  743. }
  744. g_get_color(int32 *l)
  745. {
  746.         *l = g.color.l;
  747. }
  748. /*---------------------------------------------------------------------------*/
  749. g_set_fill(int32 l)
  750. {
  751.         g.fill.l = l;
  752.         d_set_fill(g.fill.l);
  753. }
  754. g_get_fill(int32 *l)
  755. {
  756.         *l = g.fill.l;
  757. }
  758. /*---------------------------------------------------------------------------*/
  759. g_beginclip() {
  760.         d_beginclip(); }
  761. g_endclip() {
  762.         d_endclip(); }
  763. /*---------------------------------------------------------------------------*/
  764. static int ngsave;
  765. static char *gsave[100];
  766.  
  767. g_gsave()
  768. {
  769.         ngsave++;
  770.         if (ngsave>=99) {
  771.                 gprint("Over 99 GSAVE's, probably a loop in your code\n");
  772.                 return;
  773.         }
  774.         gsave[ngsave] = myallocz(SIZEOFSTATE+10);
  775.         g_get_state(gsave[ngsave]);
  776. }
  777. g_grestore()
  778. {
  779.         static double a,b;
  780.         g_flush();
  781.         if (ngsave==0) {
  782.                 gprint("Attempt to GRESTORE at top of stack\n");
  783.                 if (gle_debug>0) a = a/b;
  784.                 return;
  785.         }
  786.         g_set_state(gsave[ngsave]);
  787.         myfree(gsave[ngsave]);
  788.         ngsave--;
  789. }
  790. g_get_state(char *s)
  791. {
  792.         memcpy(s,&g,SIZEOFSTATE);
  793. }
  794. g_set_state(char *s)
  795. {
  796.         memcpy(tmpimg,g.image,3*3*8);
  797.         memcpy(&g,s,SIZEOFSTATE);
  798.         memcpy(tmpimg2,g.image,3*3*8);
  799.         memcpy(g.image,tmpimg,3*3*8);
  800.         g_set_matrix(tmpimg2);
  801.         d_set_color(g.color.l);
  802.         d_set_fill(g.fill.l);
  803.         d_set_line_width(g.lwidth);
  804.         d_set_line_style(g.lstyle);
  805.         d_set_line_styled(g.lstyled);
  806.         test_unit();
  807. }
  808.         /*                 12,4,-.5,-.5,0.35,        original dot */
  809. struct mark_struct { int ff; int cc; double rx; double ry; double scl;};
  810. struct mark_struct minf[61];
  811. extern char *mrk_name[];
  812. extern char *mrk_fname[];
  813.  
  814. /* struct mark_struct { int ff, int cc, double rx, double ry, double scl;}; */
  815. extern char *mark_name[];
  816. extern char *mark_sub[];
  817. extern int mark_subp[];
  818. extern int nmark;
  819.  
  820. extern int nmrk;
  821. g_marker(int i, double sz)
  822. {
  823.         g_marker2(i,sz,1.0);
  824. }
  825. g_marker2(int i, double sz, double dval)
  826. {
  827.         static double cx,cy,h,scale;
  828.         static double x1,y1,x2,y2;
  829.         int otype;
  830.         if (i<0) {{
  831.                 char *stk_str[6];
  832.                 double stk[6];
  833.                 int nstk=2;
  834.                 ++i;
  835.                 i = -i;
  836.                 if (mark_subp[i]==-1) {{
  837.                         int idx,zret,np,plist;
  838.                         mark_subp[i] = sub_find(mark_sub[i],&idx,&zret,&np,(int **) &plist);
  839.                         if (mark_subp[i] == 0)  {
  840.                                 gprint("You MUST define the sub before defining the marker\n");
  841.                                 return;
  842.                         }
  843.                 }}
  844.                 stk[1] = sz;
  845.                 stk[2] = dval;
  846.                 g_get_xy(&cx,&cy);
  847.                 sub_call(mark_subp[i],(double *) &stk,(char **) &stk_str,&nstk,&otype);
  848.                 g_move(cx,cy);
  849.                 return;
  850.         }}
  851.         if (i<1 || i>nmrk) {gprint("Invalid marker number %d \n",i); return;}
  852.         g_get_xy(&cx,&cy);
  853.         g_get_hei(&h);
  854.         i--;
  855.         scale = minf[i].scl*sz;
  856.         g_set_hei(scale);
  857.         if (minf[i].ff == 0) minf[i].ff = pass_font(mrk_fname[i]);
  858.         if (minf[i].ff == -1) {
  859.                 minf[i].ff = pass_font(mrk_fname[i]);
  860.                 char_bbox(minf[i].ff,minf[i].cc,&x1,&y1,&x2,&y2);
  861.                 minf[i].ry = (minf[i].ry + -y1-(y2-y1)/2.0);
  862.                 minf[i].rx = (minf[i].rx + -x1-(x2-x1)/2.0);
  863.         }
  864.  
  865.         g_move(cx+minf[i].rx*scale, cy+minf[i].ry*scale);
  866.         g_char(minf[i].ff,minf[i].cc);
  867.         g_move(cx,cy);
  868.         g_set_hei(h);
  869. }
  870. g_defmarker(char *mname,char *font, int ccc, double dx, double dy, double sz, int autodx)
  871. {
  872.         int i;
  873.         if (nmrk>61-1) {gprint("Too many markers defined \n"); return;}
  874.         i = nmrk;
  875.         nmrk++;
  876.         mrk_name[i] = sdup(mname);
  877.         mrk_fname[i] = sdup(font);
  878.         minf[i].ff = 0;
  879.         if (autodx) minf[i].ff = -1;
  880.         minf[i].cc = ccc;
  881.         minf[i].rx = dx;
  882.         minf[i].ry = dy;
  883.         minf[i].scl = sz;
  884. }
  885. g_marker_def(char *mname,char *subname)
  886. {
  887.         int i;
  888.         for (i=0; i<nmark; i++) if (strcmp(mname,mark_name[i])==0) {
  889.                 myfree(mark_name[i]);
  890.                 myfree(mark_sub[i]);
  891.                 nmark--;
  892.                 break;
  893.         }
  894.         nmark++;
  895.         mark_name[i] = sdup(mname);
  896.         mark_sub[i] = sdup(subname);
  897.         mark_subp[i] = -1;
  898. }
  899. g_char(int font, int cc)
  900. {
  901.         d_char(font,cc);
  902. }
  903. g_text(char *ss)
  904. {
  905.         text_block(UC ss,0.0,g.just);
  906. }
  907. g_set_just(int jj)
  908. {
  909.         g.just = jj;
  910. }
  911. g_set_font(int jj)
  912. {
  913.         if (jj==0) return;
  914.         font_load_metric(jj);
  915.         g.fontn = jj;
  916. }
  917. g_set_hei(double h)
  918. {
  919.         if (h==0) {
  920.                 gprint("========================************ HEIGHT SET TO ZERO\n");
  921.                 return;
  922.         }
  923.         g.fontsz = h;
  924. }
  925. g_get_just(int *jj)
  926. {
  927.         *jj = g.just;
  928. }
  929. g_get_font(int *jj)
  930. {
  931.         *jj = g.fontn;
  932. }
  933. g_get_hei(double *h)
  934. {
  935.         *h = g.fontsz;
  936. }
  937. g_postscript(char *fname,double wx, double wy)
  938. {
  939. char inbuff[200];
  940. FILE *fptr;
  941. int i;
  942. char *s;
  943. double bx1=0,by1=0,bx2,by2,x,y,cx,cy;
  944.         g_get_type(inbuff);
  945.         if (strstr(inbuff,"PS")== NULL) {
  946.                 g_get_xy(&cx,&cy);
  947.                 g_box_stroke(cx,cy,cx+wx,cy+wy);
  948.                 return;
  949.         }
  950.         fptr = fopen(fname,"r");
  951.         if (fptr==NULL) {
  952.                 gprint("Unable to open input file {%s} \n",fname);
  953.                 perror("Reason");
  954.                 return;
  955.         }
  956.         for (;!feof(fptr);) {
  957.           if (fgets(inbuff,190,fptr)!=NULL) {
  958.                 if (strncmp(inbuff,"%%BoundingBox:",14)==0) {
  959.                         s = strtok(inbuff," :\t");
  960.                         bx1 = atof(strtok(0," :\t"));
  961.                         by1 = atof(strtok(0," :\t"));
  962.                         bx2 = atof(strtok(0," :\t"));
  963.                         by2 = atof(strtok(0," :\t"));
  964.                 }
  965.           }
  966.         }
  967.  
  968.         g_devcmd("/GLESTATE save def \n");
  969.         g_devcmd("gsave\n");
  970.         g_devcmd("/a4small {} def /legal {} def\n");
  971.         g_devcmd("/letter {} def /note {} def /copypage {} def \n");
  972.         g_devcmd("/erasepage {} def /showpage {} def \n");
  973.         rewind(fptr);
  974.         g_gsave();
  975.         g_get_xy(&cx,&cy);
  976.         g_translate(cx,cy);
  977.         bx2 -= bx1;
  978.         by2 -= by1;
  979.         if (bx2==0 || by2==0) {gprint("Invalid EPS file\n"); return;}
  980.         g_move(0.0,0.0);
  981.         g_scale(wx/bx2,wx/bx2); /* use wy/by2 to change aspect ratio */
  982.         g_translate(-bx1,-by1);
  983.         g_devcmd("0 setgray 0 setlinecap 0 setlinewidth 0 setlinejoin\n");
  984.         g_devcmd("10 setmiterlimit [] 0 setdash\n");
  985.         for (;!feof(fptr);) {
  986.           if (fgets(inbuff,200,fptr)!=NULL) {
  987.                 g_devcmd(inbuff);
  988.           }
  989.         }
  990.         fclose(fptr);
  991.         g_devcmd("grestore GLESTATE restore \n");
  992.         g_grestore();
  993. }
  994. g_devcmd(char *s)
  995. {
  996.         d_devcmd(s);
  997. }
  998.